#include "solar/trunk/NEdit.h"
/*
16777235 	上
16777237	下
16777234	左
16777236	右
16777251    ALT
32			空格
16777217	制表符
16777248    shift
91 			[
93			]
45			-
61			=
59			;
39			'
44			,
46			.
47			/
92			\

67          "\u0003"        ctrl+x
86          "\u0016"        ctrl+v
65          "\u0001"        ctrl+a
*/
//======================================================================NPlainEdit
NPlainEdit::NPlainEdit(QWidget *parent){
    RdoMap_Integer["Size-W"] = this->size().width();
    RdoMap_Integer["Size-H"] = this->size().height();
    RdoMap_Switch.insert("FollowCursor", true);
    RdoMap_Switch.insert("AssistButtonLoadLayout", false);
    RdoMap_Integer.insert("VerticalScrollValue", 0);
    setParent(parent);
}


void NPlainEdit::insertPlainText(const QString &Text){
    if (!RdoMap_Switch["FollowCursor"])
    {
        retentionFoodList.append(Text);
        if (toPlainText().isEmpty()) RdoMap_Switch["FollowCursor"] = true;
    }
    else
    {
        if (!retentionFoodList.isEmpty())
        {
            foreach(QString hstrText, retentionFoodList) pushText(hstrText);
            diary(QString("retention list count: %1 and loaded, clear now").arg(retentionFoodList.size()), Diary::Debug)
            retentionFoodList.clear();
        }
        pushText(Text);
    }
}


void NPlainEdit::dragEnterEvent(QDragEnterEvent *Event){
    if (!Event->mimeData()->text().isEmpty()){
         //重要的一行代码，与hastext相关联，是显示文件接受图标是否正常的标志，但对实际操无影响
         Event->accept();
     } else {
         Event->ignore();
    }
}


void NPlainEdit::dropEvent(QDropEvent *Event){
    QString AbsforSuffix = "[a-zA-Z]\\s*:\\s*[\\|/].*\\..{3,%1}";
    QString AbsHeadSuffix = "[a-zA-Z]\\s*:\\s*[\\\\|/]";
    QString dropText = Event->mimeData()->text().remove(QRegularExpression("file\\W+"));
    QStringList DspsPath = definfc.ExtractPath(dropText,
                                           AbsforSuffix.arg(6),
                                           AbsHeadSuffix);
    foreach(QString path, DspsPath)
    {
        insertPlainText(Reader::g_reader(path));
    }
    emit msev_drop(std::make_pair(true, DspsPath));
}


void NPlainEdit::dragLeaveEvent(QDragLeaveEvent*){
    emit msev_drop(std::make_pair(false, QStringList()));
}


void NPlainEdit::mouseReleaseEvent(QMouseEvent *Event){
    if (Event->button() == Qt::LeftButton)
    {
        emit msev_rls(true);
    }
}


void NPlainEdit::enterEvent(QEnterEvent *){
    addAssistButtonLayout();
    emit msev_etr(true);
}


void NPlainEdit::leaveEvent(QEvent *){
    emit msev_etr(false);
    foreach(QWidget *wid, addAssistFuncWidgets)
    {
        wid->setVisible(false);
    }
}


void NPlainEdit::resizeEvent(QResizeEvent *Event){
    int width = Event->size().width();
    int height = Event->size().height();
    //获取比例，当窗口尺寸发生变化时，将前后尺寸做对比得出比例，
    //当比例小于1时，赋值为1
    if ((RdoMap_Integer.count(RPLKEY.WIN_SIZE_W) &&
        width != RdoMap_Integer[RPLKEY.WIN_SIZE_W]) ||
        (RdoMap_Integer.count(RPLKEY.WIN_SIZE_H) &&
        height != RdoMap_Integer[RPLKEY.WIN_SIZE_H])){
        RdoMap_Switch["SizeChange"] = true;
    }
    else
    {
        RdoMap_Switch["SizeChange"] = false;
    }
    RdoMap_Integer[RPLKEY.WIN_SIZE_W] = width;
    RdoMap_Integer[RPLKEY.WIN_SIZE_H] = height;
    update();
}


void NPlainEdit::addAssistButtonLayout(){
    QList<QPoint> addAssistFuncPoints;
    int vtcWidth = 0;
    int hrztHeight = 0;
    bool vtcVsb = verticalScrollBar()->isVisible();
    bool hrztVsb = horizontalScrollBar()->isVisible();
    if (vtcVsb) vtcWidth = verticalScrollBar()->width();
    if (hrztVsb) hrztHeight = horizontalScrollBar()->height();
    if (!addAssistFuncWidgets.isEmpty())
    {
        int globalNum = 0;
        foreach(QWidget *wid, addAssistFuncWidgets)
        {
            bool isChange = (RdoMap_Integer["scrWidth"] != vtcWidth || RdoMap_Integer["scrHeight"] != hrztHeight);
            if (RdoMap_Switch["AssistButtonLoadLayout"] && !isChange && !RdoMap_Switch["SizeChange"])
            {
                wid->setVisible(true);
            }
            else
            {
                int m = RdoMap_Integer["AssistFuncWidgetMargins"];
                int x = 0;
                int y = 0;
                int szw = width();
                int szh = height();
                int w = wid->width();
                int h = wid->height();
                if (!w || !h) emit pixmap_empty_error(wid->objectName());
                int L = addAssistFuncLocations[globalNum];
                int loopRange = addAssistFuncWidgets.size();
                int xf = 0;
                bool tone_up = true; //# 边界标志，为true则坐标 增加边界值
                while (xf < loopRange)
                {
                    if (RdoMap_Integer["LayoutClock"] == NT::CUT_CLOCKWISE)
                    {
                        if (L == NT::LOCALTION_ROOF_LEFT)
                        {
                            if (tone_up) w = w + m;
                            x = m + xf * w;
                            y = m;
                            if (x + w * 2 + m > szw)
                            {
                                L = NT::LOCALTION_ROOF_RIGHT;
                                xf = 0;
                            }
                        }
                        else if (L == NT::LOCALTION_ROOF_RIGHT)
                        {
                            if (tone_up) h = h + m;
                            x = szw - w - m - vtcWidth;
                            y = m + xf * h;
                            if (y + h * 2 + m > szh)
                            {
                                L = NT::LOCALTION_BOTTON_RIGHT;
                                xf = 0;
                            }

                        }
                        else if (L == NT::LOCALTION_BOTTON_LEFT)
                        {
                            if (tone_up) h = h + m;
                            y = szh - h - m - xf * h - hrztHeight;
                            x = m;;
                            if (y < h)
                            {
                                L = NT::LOCALTION_ROOF_LEFT;
                                xf = 0;
                            }
                        }
                        else if (L == NT::LOCALTION_BOTTON_RIGHT)
                        {
                            if (tone_up) w = w+ m;
                            x = szw - w - m - xf * w - vtcWidth;
                            y = szh - h - m - hrztHeight;
                            if (x < w)
                            {
                                L = NT::LOCALTION_BOTTON_LEFT;
                                xf = 0;
                            }
                        }
                        else if (L == NT::LOCALTION_CENTER_BOTTON)
                        {
                            if (tone_up) w = w + m;
                            y = szh - h - m - hrztHeight;
                            x = szw / 2 - w / 2 - xf * w;
                            if (x < w)
                            {
                                L = NT::LOCALTION_BOTTON_LEFT;
                                xf = 0;
                            }
                        }
                        else if (L == NT::LOCALTION_CENTER_ROOF)
                        {
                            if (tone_up) w = w + m;
                            x = szw / 2 - w / 2 + xf * w;
                            y = m;
                            if (x + w * 2 + m > szw)
                            {
                                L = NT::LOCALTION_ROOF_RIGHT;
                                xf = 0;
                            }
                        }
                        else if (L == NT::LOCALTION_CENTER_LEFT)
                        {
                            if (tone_up) h = h + m;
                            x = m;
                            y = szh / 2 - h / 2 - xf * h;
                            if (y < h)
                            {
                                L = NT::LOCALTION_ROOF_LEFT;
                                xf = 0;
                            }
                        }
                        else if (L == NT::LOCALTION_CENTER_RIGHT)
                        {

                            if (tone_up) h = h + m;
                             x = szw - w - m - vtcWidth;
                            y = szh / 2 - h / 2 + xf *h;
                            if (y + h * 2 + m > szh)
                            {
                                L = NT::LOCALTION_BOTTON_RIGHT;
                                xf = 0;
                            }
                        }
                    }

                    else if (RdoMap_Integer["LayoutClock"] == NT::CUT_ANTICLOCKWISE)
                    {
                        if (L == NT::LOCALTION_ROOF_LEFT)
                        {
                            if (tone_up) h = h + m;
                            x = m;
                            y = m + xf * h;
                            if (y + h * 2 + m > szh) //#存在延迟，当条件成立时，运行行if条件内的代码规避，但情况已经发生了，即当条件为 y + h + m > szh 时，错误的y坐标已经被录入，进而才运行if的代码，不符需求
                            {
                                L = NT::LOCALTION_BOTTON_RIGHT;
                                xf = 0;
                            }
                        }
                        else if (L == NT::LOCALTION_ROOF_RIGHT)
                        {
                            if (tone_up) w = w + m;
                            x = szw - w - m - vtcWidth - xf * w;
                            y = m;
                            if (x < w) //#存在延迟，当条件成立时，运行行if条件内的代码规避，但情况已经发生了，即当条件为 y + h + m > szh 时，错误的y坐标已经被录入，进而才运行if的代码，不符需求
                            {
                                L = NT::LOCALTION_BOTTON_LEFT;
                                xf = 0;
                            }

                        }
                        else if (L == NT::LOCALTION_BOTTON_LEFT)
                        {
                            if (tone_up) w = w + m;
                            y = szh - h - m - hrztHeight;
                            x = m + xf * w;;
                            if (x + w * 2 + m > szw)
                            {
                                L = NT::LOCALTION_ROOF_RIGHT;
                                xf = 0;
                            }
                        }
                        else if (L == NT::LOCALTION_BOTTON_RIGHT)//#===
                        {
                            if (tone_up) h = h + m;
                            x = szw - w - m - vtcWidth;
                            y = szh - h - m - xf * h - hrztHeight;
                            if (y < h)
                            {
                                L = NT::LOCALTION_ROOF_LEFT;
                                xf = 0;
                            }
                        }
                        else if (L == NT::LOCALTION_CENTER_BOTTON)
                        {
                            if (tone_up) w = w + m;
                            y = szh - h - m - hrztHeight;
                            x = szw / 2 - w / 2 + xf * w;
                            if (x + w * 2 + m > szw)
                            {
                                L = NT::LOCALTION_ROOF_RIGHT;
                                xf = 0;
                            }
                        }
                        else if (L == NT::LOCALTION_CENTER_ROOF)
                        {
                            if (tone_up) w = w + m;
                            x = szw / 2 - w / 2 - xf * w;
                            y = m;
                            if (x < w)
                            {
                                L = NT::LOCALTION_BOTTON_LEFT;
                                xf = 0;
                            }
                        }
                        else if (L == NT::LOCALTION_CENTER_LEFT)
                        {
                            if (tone_up) h = h + m;
                            x = m;
                            y = szh / 2 - h / 2 + xf * h;
                            if (y + h * 2 + m > szh)
                            {
                                L = NT::LOCALTION_BOTTON_RIGHT;
                                xf = 0;
                            }
                        }
                        else if (L == NT::LOCALTION_CENTER_RIGHT)
                        {

                            if (tone_up) h = h + m;
                            x = szw - w - m - vtcWidth;
                            y = szh / 2 - h / 2 - xf *h;
                            if (y < h)
                            {
                                L = NT::LOCALTION_ROOF_LEFT;
                                xf = 0;
                            }
                        }
                    }
                    QPoint point(x, y);
                    point.setX(x);
                    point.setY(y);
                    xf++;
                    if (!addAssistFuncPoints.contains(point))
                    {
                        wid->move(point);
                        wid->setVisible(true);
                        addAssistFuncPoints.append(point);
                        break;
                    }
                    else
                    {
                        tone_up = false;
                        continue;
                    }
                }

            } globalNum++;
        }
        RdoMap_Switch["AssistButtonLoadLayout"] = true;
        RdoMap_Integer["scrWidth"] = vtcWidth;
        RdoMap_Integer["scrHeight"] = hrztHeight;
    }
}


void NPlainEdit::setWheelFontBlock(int block){
    RdoMap_Integer["FontBlock"] = block;
}


void NPlainEdit::wheelEvent(QWheelEvent *Event){
    if (Event->angleDelta().y() > 0)
    {
        if (!toPlainText().isEmpty())
        {
            RdoMap_Switch["FollowCursor"] = false;
            if (RdoMap_Switch["Shift-Enter"])
            {
                QFont curFont(font());
                int fontSize = curFont.pointSize();
                if (fontSize <=RdoMap_Integer["FontBlock"]) curFont.setPointSize(fontSize + 1);
                setFont(curFont);
            }
        }
        emit msev_wheel(-1);
    }
    else
    {
        if (RdoMap_Switch["Shift-Enter"])
        {
            QFont curFont(font());
            if (curFont.pointSize() > 0) curFont.setPointSize(curFont.pointSize() - 1);
            setFont(curFont);
        }
        if (verticalScrollBar()->sliderPosition() == verticalScrollBar()->maximum())
        {
            QTextCursor Cursor = textCursor();
            Cursor.movePosition(QTextCursor::End);
            setTextCursor(Cursor);
            RdoMap_Switch["FollowCursor"] = true;
        }
        emit msev_wheel(0);
    }
    if (!RdoMap_Switch["Shift-Enter"]) QPlainTextEdit::wheelEvent(Event);
}


void NPlainEdit::keyPressEvent(QKeyEvent *Event){
    //#Enter Key
    emit KeyEvent(qMakePair(Event->key(), Event->text()));
    if(QList<int>({16777220, 16777221}).contains(Event->key()) ||
      Event->text() == "\r")
    {
        QTextCursor Cursor = textCursor();
        Cursor.movePosition(QTextCursor::End);
        setTextCursor(Cursor);
        RdoMap_Switch["FollowCursor"] = true;
    }
    else if (Event->key() == 16777248)
    {
        RdoMap_Switch["Shift-Enter"] = true;
    }
    QPlainTextEdit::keyPressEvent(Event);
}


void NPlainEdit::keyReleaseEvent(QKeyEvent *Event){
    //# CTRL Key
    if (Event->key() == 16777248)
    {
        RdoMap_Switch["Shift-Enter"] = false;
    }
    QPlainTextEdit::keyReleaseEvent(Event);
}


void NPlainEdit::paintEvent(QPaintEvent *Event){
    QPlainTextEdit::paintEvent(Event);
}


void NPlainEdit::addAssistFuncWidget(QWidget *_sec_widget, NT::LOCALTION LOCATION){
    _sec_widget->setParent(this);
    _sec_widget->setVisible(true);
    addAssistFuncWidgets.append(_sec_widget);
    RdoMap_Integer["AssistFuncWidgetMargins"] = 3;
    RdoMap_Integer["LayoutClock"] = NT::CUT_CLOCKWISE;
    addAssistFuncLocations.append(LOCATION);
}


void NPlainEdit::AssistButtonRemove(QWidget *_key_win_){
    if (_key_win_)
    {
        if (addAssistFuncWidgets.contains(_key_win_))
        {
            int indexOf = addAssistFuncWidgets.indexOf(_key_win_);
            addAssistFuncWidgets.removeAt(indexOf);
        }
    } else addAssistFuncWidgets.clear();
}


void NPlainEdit::setAssistFuncWidgetMargins(int margins){
    RdoMap_Integer["AssistFuncWidgetMargins"] = margins;
}


void NPlainEdit::setAssistFuncWidgetLayoutClock(NT::CST_BRIGHT_SPOT CLOCKWISE){
    RdoMap_Integer["LayoutClock"] = CLOCKWISE;
}


void NPlainEdit::pushText(const QString &Text){
    moveCursor(QTextCursor::End);
    QPlainTextEdit::insertPlainText(Text);
    QTextCursor Cursor = textCursor();
    Cursor.movePosition(QTextCursor::End);
    setTextCursor(Cursor);
}


void NPlainEdit::setBreakAwayFromFollow(bool Enable){
    RdoMap_Switch["FollowCursor"] = Enable;
}


QTextBlock NPlainEdit::firstVisibleBlock(){
    return QPlainTextEdit::firstVisibleBlock();
}


//======================================================================NLineEdit
NLineEdit::NLineEdit(QWidget *parent){
    RdoMap_Integer["Size-W"] = this->size().width();
    RdoMap_Integer["Size-H"] = this->size().height();
    qRegisterMetaType<QPair<int, QString>>("QPair<int, QString>");
    setParent(parent);
}


void NLineEdit::dragEnterEvent(QDragEnterEvent *Event){
    if (!Event->mimeData()->text().isEmpty()){
         //重要的一行代码，与hastext相关联，是显示文件接受图标是否正常的标志，但对实际操无影响
         Event->accept();
    } else {
         Event->ignore();
    }
}


void NLineEdit::dropEvent(QDropEvent *Event){
    QString AbsforSuffix = "[a-zA-Z]\\s*:\\s*[\\|/].*\\..{3,%1}";
    QString AbsHeadSuffix = "[a-zA-Z]\\s*:\\s*[\\\\|/]";
    QStringList DspsPath = definfc.ExtractPath(Event->mimeData()->text(),
                                           AbsforSuffix.arg(6),
                                           AbsHeadSuffix);
    emit msev_drop(std::make_pair(true, DspsPath));
}


void NLineEdit::dragLeaveEvent(QDragLeaveEvent*){
    emit msev_drop(std::make_pair(false, QStringList()));
}


void NLineEdit::mouseReleaseEvent(QMouseEvent*){
    emit msev_rls(true);
    emit msnm_rls(objectName());
}


void NLineEdit::keyPressEvent(QKeyEvent *Event){
    emit KeyEvent(qMakePair(Event->key(), Event->text()));
    if (Event->key() == 16777248)
    {
        RdoMap_Switch["Shift-Enter"] = true;
    }
    if (objectName() == "SP_commandEdit" &&
        SpecialKey.contains(Event->key()))
    {
        setText(text() + "->");
    }
    else
    {
        QLineEdit::keyPressEvent(Event);
    }
}


void NLineEdit::keyReleaseEvent(QKeyEvent *Event){
    if (Event->key() == 16777248)
    {
        RdoMap_Switch["Shift-Enter"] = false;
    }
    if (objectName() != "SP_commandEdit")
    {
        QLineEdit::keyReleaseEvent(Event);
    }
}


